import { defineStore } from 'pinia'
import { computed, ref } from 'vue'

import {
  getConfig,
  isEqual,
  isNumber,
  isUrl,
  type multiType,
  type positionType,
  responsiveStorageNameSpace,
  routerArrays,
  storageLocal,
} from '../utils'
import { usePermissionStore } from './permission'

export const useMultiTagsStore = defineStore('pure-multiTags', () => {
  // state
  const multiTags = ref<multiType[]>(
    storageLocal().getItem<StorageConfigs>(`${responsiveStorageNameSpace()}configure`)
      ?.multiTagsCache
      ? (storageLocal().getItem<StorageConfigs>(
          `${responsiveStorageNameSpace()}tags`,
        ) as multiType[])
      : [...routerArrays, ...usePermissionStore().flatteningRoutes.filter(v => v?.meta?.fixedTag)],
  )

  const multiTagsCache = ref<boolean | undefined>(
    storageLocal().getItem<StorageConfigs>(`${responsiveStorageNameSpace()}configure`)
      ?.multiTagsCache,
  )

  // getters
  const getMultiTagsCache = computed(() => multiTagsCache.value)

  // actions
  function multiTagsCacheChange(newMultiTagsCache: boolean) {
    multiTagsCache.value = newMultiTagsCache
    if (newMultiTagsCache) {
      storageLocal().setItem(`${responsiveStorageNameSpace()}tags`, multiTags.value)
    } else {
      storageLocal().removeItem(`${responsiveStorageNameSpace()}tags`)
    }
  }

  function tagsCache(tags: multiType[]) {
    getMultiTagsCache.value && storageLocal().setItem(`${responsiveStorageNameSpace()}tags`, tags)
  }

  function handleTags<T>(
    mode: string,
    value?: T | multiType,
    position?: positionType,
  ): T | undefined {
    switch (mode) {
      case 'equal':
        multiTags.value = value as any
        tagsCache(multiTags.value)
        break
      case 'push':
        {
          const tagVal = value as multiType
          // 不添加到标签页
          if (tagVal?.meta?.hiddenTag) return
          // 如果是外链无需添加信息到标签页
          if (isUrl(tagVal?.name)) return
          // 如果title为空拒绝添加空信息到标签页
          if (tagVal?.meta?.title.length === 0) return
          // showLink:false 不添加到标签页
          // if (isBoolean(tagVal?.meta?.showLink) && !tagVal?.meta?.showLink) return
          const tagPath = tagVal.path
          // 判断tag是否已存在
          const tagHasExits = multiTags.value.some(tag => {
            return tag.path === tagPath
          })

          // 判断tag中的query键值是否相等
          const tagQueryHasExits = multiTags.value.some(tag => {
            return isEqual(tag?.query, tagVal?.query)
          })

          // 判断tag中的params键值是否相等
          const tagParamsHasExits = multiTags.value.some(tag => {
            return isEqual(tag?.params, tagVal?.params)
          })

          if (tagHasExits && tagQueryHasExits && tagParamsHasExits) return value as any

          // 动态路由可打开的最大数量
          const dynamicLevel = tagVal?.meta?.dynamicLevel ?? -1
          if (dynamicLevel > 0) {
            if (multiTags.value.filter(e => e?.path === tagPath).length >= dynamicLevel) {
              // 如果当前已打开的动态路由数大于dynamicLevel，替换第一个动态路由标签
              const index = multiTags.value.findIndex(item => item?.path === tagPath)
              index !== -1 && multiTags.value.splice(index, 1)
            }
          }
          multiTags.value.push(value as multiType)
          tagsCache(multiTags.value)
          if (getConfig()?.MaxTagsLevel && isNumber(getConfig().MaxTagsLevel)) {
            const maxTagsLevel = getConfig().MaxTagsLevel as number
            if (multiTags.value.length > maxTagsLevel) {
              multiTags.value.splice(1, 1)
            }
          }
        }
        break
      case 'splice':
        if (!position) {
          const index = multiTags.value.findIndex(v => v.path === value)
          if (index === -1) return
          multiTags.value.splice(index, 1)
        } else {
          multiTags.value.splice(position?.startIndex ?? 0, position?.length ?? 0)
        }
        tagsCache(multiTags.value)
        return multiTags.value as any
      case 'slice':
        return multiTags.value.slice(-1) as any
    }
  }

  return {
    multiTags,
    multiTagsCache,
    getMultiTagsCache,
    multiTagsCacheChange,
    tagsCache,
    handleTags,
  }
})
